<!-- 商品详情大图上传组件 -->
<template>
  <div class="detail-image-upload">
    <!-- 当前选中的图片显示 -->
    <div v-if="displayValue" class="current-image">
      <el-image :src="displayValue" :style="props.style" />
      <el-icon class="delete-btn" @click="handleDelete">
        <CircleCloseFilled />
      </el-icon>
    </div>

    <!-- 选择/上传按钮 -->
    <div v-if="!displayValue" class="upload-actions">
      <el-button type="primary" plain @click="showImageSelector = true">
        <el-icon><Picture /></el-icon>
        从预设图片选择
      </el-button>
      <span class="or-text">或</span>
      <el-upload
        class="custom-upload"
        :show-file-list="false"
        :accept="props.accept"
        :before-upload="handleBeforeUpload"
        :http-request="handleUpload"
        :on-success="onSuccess"
        :on-error="onError"
      >
        <el-button type="success" plain>
          <el-icon><Upload /></el-icon>
          上传新图片
        </el-button>
      </el-upload>
    </div>

    <!-- 如果有图片，显示重新选择按钮 -->
    <div v-if="displayValue" class="reselect-actions">
      <el-button
        size="small"
        type="primary"
        plain
        style="margin-top: 5px"
        @click="showImageSelector = true"
      >
        重新选择预设图片
      </el-button>
      <el-upload
        class="custom-upload"
        :show-file-list="false"
        :accept="props.accept"
        :before-upload="handleBeforeUpload"
        :http-request="handleUpload"
        :on-success="onSuccess"
        :on-error="onError"
      >
        <el-button size="small" type="success" plain>重新上传图片</el-button>
      </el-upload>
    </div>

    <!-- 预设图片选择对话框 -->
    <el-dialog v-model="showImageSelector" title="选择商品详情大图" width="800px">
      <div class="preset-images">
        <div
          v-for="image in presetImages"
          :key="image.name"
          class="preset-image-item"
          :class="{ selected: selectedPresetImage === image.url }"
          @click="selectedPresetImage = image.url"
        >
          <el-image :src="image.url" fit="cover" />
          <div class="image-name">{{ image.displayName }}</div>
          <div v-if="selectedPresetImage === image.url" class="selected-overlay">
            <el-icon><Check /></el-icon>
          </div>
        </div>
      </div>
      <template #footer>
        <div class="dialog-footer">
          <el-button @click="showImageSelector = false">取消</el-button>
          <el-button
            type="primary"
            :disabled="!selectedPresetImage"
            @click="handleSelectPresetImage"
          >
            确定选择
          </el-button>
        </div>
      </template>
    </el-dialog>
  </div>
</template>

<script setup>
import FileAPI from "@/api/file.api";

const props = defineProps({
  /**
   * 请求携带的额外参数
   */
  data: {
    type: Object,
    default: () => {
      return {};
    },
  },
  /**
   * 上传文件的参数名
   */
  name: {
    type: String,
    default: "file",
  },
  /**
   * 最大文件大小（单位：M）
   */
  maxFileSize: {
    type: Number,
    default: 10,
  },
  /**
   * 上传图片格式，默认支持所有图片(image/*)，指定格式示例：'.png,.jpg,.jpeg,.gif,.bmp'
   */
  accept: {
    type: String,
    default: "image/*",
  },
  /**
   * 自定义样式，用于设置组件的宽度和高度等其他样式
   */
  style: {
    type: Object,
    default: () => {
      return {
        width: "200px",
        height: "150px",
      };
    },
  },
});

const modelValue = defineModel("modelValue", {
  type: String,
  default: () => "",
});
const baseUrl = "https://d8ks2qr9fr6p2.cloudfront.net/homeAssets";
// 预设图片列表
const presetImages = [
  {
    name: "3SideSealBag.jpg",
    displayName: "3SideSealBag",
    url: baseUrl + "/images/category/3SideSealBag.jpg",
  },
  {
    name: "BackSealBag.jpg",
    displayName: "BackSealBag",
    url: baseUrl + "/images/category/BackSealBag.jpg",
  },
  {
    name: "FlatBottomBag.jpg",
    displayName: "FlatBottomBag",
    url: baseUrl + "/images/category/FlatBottomBag.jpg",
  },
  {
    name: "FlatBottomBag1.jpg",
    displayName: "FlatBottomBag1",
    url: baseUrl + "/images/category/FlatBottomBag1.jpg",
  },
  {
    name: "RollFilm.jpg",
    displayName: "RollFilm",
    url: baseUrl + "/images/category/RollFilm.jpg",
  },
  {
    name: "SideGussetBag.jpg",
    displayName: "SideGussetBag",
    url: baseUrl + "/images/category/SideGussetBag.jpg",
  },
  {
    name: "SpoutPouch.jpg",
    displayName: "SpoutPouch",
    url: baseUrl + "/images/category/SpoutPouch.jpg",
  },
  {
    name: "StandUpBag.jpg",
    displayName: "StandUpBag",
    url: baseUrl + "/images/category/StandUpBag.jpg",
  },
  {
    name: "UniqueShapeBag.jpg",
    displayName: "UniqueShapeBag",
    url: baseUrl + "/images/category/UniqueShapeBag.jpg",
  },
  {
    name: "VacuumBag.jpg",
    displayName: "VacuumBag",
    url: baseUrl + "/images/category/VacuumBag.jpg",
  },
];

// 用于显示的图片URL
const displayValue = ref("");
// 是否显示图片选择器
const showImageSelector = ref(false);
// 当前选中的预设图片
const selectedPresetImage = ref("");

// 解析JSON字符串并提取第一个图片的URL
const parseModelValue = () => {
  try {
    if (!modelValue.value) return "";

    const parsedData = JSON.parse(modelValue.value);
    if (Array.isArray(parsedData) && parsedData.length > 0 && parsedData[0].url) {
      return parsedData[0].url;
    }
    return "";
  } catch (error) {
    console.error("解析JSON字符串失败:", error);
    return modelValue.value; // 如果解析失败，直接返回原始值
  }
};

// 监听modelValue变化，更新显示值
watch(
  modelValue,
  () => {
    displayValue.value = parseModelValue();
  },
  { immediate: true }
);

/**
 * 限制用户上传文件的格式和大小
 */
function handleBeforeUpload(file) {
  // 校验文件类型
  const acceptTypes = props.accept.split(",").map((type) => type.trim());

  // 检查文件格式是否符合 accept
  const isValidType = acceptTypes.some((type) => {
    if (type === "image/*") {
      return file.type.startsWith("image/");
    } else if (type.startsWith(".")) {
      return file.name.toLowerCase().endsWith(type);
    } else {
      return file.type === type;
    }
  });

  if (!isValidType) {
    ElMessage.warning(`上传文件的格式不正确，仅支持：${props.accept}`);
    return false;
  }

  // 限制文件大小
  if (file.size > props.maxFileSize * 1024 * 1024) {
    ElMessage.warning("上传图片不能大于" + props.maxFileSize + "M");
    return false;
  }
  return true;
}

/**
 * 上传图片
 */
function handleUpload(options) {
  return new Promise((resolve, reject) => {
    const file = options.file;

    const formData = new FormData();
    formData.append(props.name, file);

    // 处理附加参数
    Object.keys(props.data).forEach((key) => {
      formData.append(key, props.data[key]);
    });

    FileAPI.upload(formData)
      .then((data) => {
        resolve(data);
      })
      .catch((error) => {
        reject(error);
      });
  });
}

/**
 * 删除图片
 */
function handleDelete() {
  modelValue.value = "[]";
  displayValue.value = "";
}

/**
 * 选择预设图片
 */
function handleSelectPresetImage() {
  if (selectedPresetImage.value) {
    const selectedImage = presetImages.find((img) => img.url === selectedPresetImage.value);
    const newValue = JSON.stringify([{ name: selectedImage.displayName, url: selectedImage.url }]);
    modelValue.value = newValue;
    displayValue.value = selectedImage.url;
    ElMessage.success("选择成功");
  }
  showImageSelector.value = false;
  selectedPresetImage.value = "";
}

/**
 * 上传成功回调
 */
const onSuccess = (fileInfo, uploadFile) => {
  ElMessage.success("上传成功");
  const newValue = JSON.stringify([
    { name: uploadFile.name || fileInfo.name || "未命名", url: fileInfo.url },
  ]);
  modelValue.value = newValue;
  displayValue.value = fileInfo.url;
};

/**
 * 上传失败回调
 */
const onError = (error) => {
  console.log("onError");
  ElMessage.error("上传失败: " + error.message);
};
</script>

<style scoped lang="scss">
.detail-image-upload {
  .current-image {
    position: relative;
    display: inline-block;
    border: 1px solid var(--el-border-color);
    border-radius: 5px;
    overflow: hidden;

    &:hover {
      border-color: var(--el-color-primary);
    }

    .delete-btn {
      position: absolute;
      top: 5px;
      right: 5px;
      font-size: 16px;
      color: #ff7901;
      cursor: pointer;
      background: rgba(255, 255, 255, 0.8);
      border-radius: 100%;
      padding: 2px;

      &:hover {
        color: #ff4500;
        background: rgba(255, 255, 255, 0.9);
      }
    }
  }

  .upload-actions {
    display: flex;
    align-items: center;
    gap: 10px;

    .or-text {
      color: var(--el-text-color-regular);
      font-size: 14px;
    }

    .custom-upload {
      display: inline-block;
    }
  }

  .reselect-actions {
    margin-top: 10px;
    display: flex;
    gap: 10px;

    .custom-upload {
      display: inline-block;
    }
  }

  .preset-images {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
    gap: 15px;
    max-height: 400px;
    overflow-y: auto;

    .preset-image-item {
      position: relative;
      border: 2px solid var(--el-border-color);
      border-radius: 8px;
      overflow: hidden;
      cursor: pointer;
      transition: all 0.3s ease;

      &:hover {
        border-color: var(--el-color-primary);
        transform: translateY(-2px);
        box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
      }

      &.selected {
        border-color: var(--el-color-primary);
        box-shadow: 0 0 0 2px rgba(64, 158, 255, 0.2);
      }

      .el-image {
        width: 100%;
        height: 100px;
      }

      .image-name {
        padding: 8px;
        font-size: 12px;
        text-align: center;
        background: var(--el-bg-color);
        color: var(--el-text-color-regular);
      }

      .selected-overlay {
        position: absolute;
        top: 5px;
        right: 5px;
        width: 20px;
        height: 20px;
        background: var(--el-color-primary);
        color: white;
        border-radius: 50%;
        display: flex;
        align-items: center;
        justify-content: center;
        font-size: 12px;
      }
    }
  }
}
</style>
